package com.tool.app.utils;


import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.icepdf.core.pobjects.Document;
import org.icepdf.core.pobjects.Page;
import org.icepdf.core.pobjects.fonts.FontManager;
import org.icepdf.core.util.GraphicsRenderingHints;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

public class PdfUtil {

	/**
	 * pdf转一张图片写出
	 * 横向拼接
	 *
	 * @param response
	 * @param in
	 */
	public static void convertPdfToImageX(HttpServletResponse response, InputStream in) {
		try {
			Document document = new Document();
			document.setInputStream(in, null);  //参数二: pdf密码
			//自定义字体位置
			String fontPath = "classpath:/font, C:/font";
			//初始化自定义字体
			FontManager.getInstance().readSystemFonts(fontPath.split(","));
			int pageCount = document.getNumberOfPages();
			if (pageCount > 0) {
				int rotation = 0;  //旋转角度
				int scale = 2; //缩放比例
				BufferedImage pageImage = (BufferedImage) document.getPageImage(0, GraphicsRenderingHints.SCREEN,
						Page.BOUNDARY_CROPBOX, rotation, scale);
				BufferedImage combinedImage;
				if (pageCount == 1) {
					combinedImage = pageImage;
				} else {
					combinedImage = new BufferedImage(pageImage.getWidth() * pageCount, pageImage.getHeight(),
							BufferedImage.TYPE_INT_RGB);
					Graphics2D graphics = combinedImage.createGraphics();
					graphics.drawImage(pageImage, 0, 0, null);
					for (int pageIndex = 1; pageIndex < pageCount; pageIndex++) {
						pageImage = (BufferedImage) document.getPageImage(pageIndex, GraphicsRenderingHints.SCREEN,
								Page.BOUNDARY_CROPBOX, rotation, scale);
						//追加图形
						graphics.drawImage(pageImage, pageIndex * pageImage.getWidth(), 0, pageImage.getWidth(), pageImage.getHeight(), null);
					}
					graphics.dispose();
				}
				response.setContentType("image/jpeg");
				ImageIO.write(combinedImage, "jpg", response.getOutputStream());
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}



	/**
	 * pdf转一张图片写出
	 * 纵向拼接
	 *
	 * @param response
	 * @param in
	 */
	public static void convertPdfToImage(HttpServletResponse response, InputStream in) {
		try {
			Document document = new Document();
			document.setInputStream(in, null);  //参数二: pdf密码
			//自定义字体位置
			//String fontPath = "classpath:/font, C:/font";
			//初始化自定义字体
			//FontManager.getInstance().readSystemFonts(fontPath.split(","));
			int pageCount = document.getNumberOfPages();
			if (pageCount > 0) {
				int rotation = 0;  //旋转角度
				int scale = 2; //缩放级别
				BufferedImage pageImage = (BufferedImage) document.getPageImage(0, GraphicsRenderingHints.SCREEN,
						Page.BOUNDARY_CROPBOX, rotation, scale);
				BufferedImage combinedImage;
				if (pageCount == 1) {
					combinedImage = pageImage;
				} else {
					combinedImage = new BufferedImage(pageImage.getWidth(), pageImage.getHeight() * pageCount,
							BufferedImage.TYPE_INT_RGB);
					Graphics2D graphics = combinedImage.createGraphics();
					graphics.drawImage(pageImage, 0, 0, null);
					for (int pageIndex = 1; pageIndex < pageCount; pageIndex++) {
						pageImage = (BufferedImage) document.getPageImage(pageIndex, GraphicsRenderingHints.SCREEN,
								Page.BOUNDARY_CROPBOX, rotation, scale);
						//追加图形
						graphics.drawImage(pageImage, 0, pageIndex * pageImage.getHeight(), null);
						//裁剪图形
						//pageImage.getSubimage(0, 0, pageImage.getWidth(), targetHeight);
					}
					graphics.dispose();
				}
				response.setContentType("image/jpeg");
				ImageIO.write(combinedImage, "jpg", response.getOutputStream());
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}


	/**
	 * pdf转图片base64
	 *
	 * @param in
	 */
	public static String convertPdfToImageBase64(InputStream in) {
		try {
			Document document = new Document();
			document.setInputStream(in, null);  //参数二: pdf密码
			int pageCount = document.getNumberOfPages();
			if (pageCount > 0) {
				int rotation = 0;  //旋转角度
				int zoom = 2; //缩放级别
				BufferedImage pageImage = (BufferedImage) document.getPageImage(0, GraphicsRenderingHints.SCREEN,
						Page.BOUNDARY_CROPBOX, rotation, zoom);
				BufferedImage combinedImage;
				if (pageCount == 1) {
					combinedImage = pageImage;
				} else {
					combinedImage = new BufferedImage(pageImage.getWidth(), pageImage.getHeight() * pageCount,
							BufferedImage.TYPE_INT_RGB);
					Graphics2D graphics = combinedImage.createGraphics();
					graphics.drawImage(pageImage, 0, 0, null);
					for (int pageIndex = 1; pageIndex < pageCount; pageIndex++) {
						pageImage = (BufferedImage) document.getPageImage(pageIndex, GraphicsRenderingHints.SCREEN,
								Page.BOUNDARY_CROPBOX, rotation, zoom);
						//追加图形
						graphics.drawImage(pageImage, 0, pageIndex * pageImage.getHeight(), null);
						//裁剪图形
						//pageImage.getSubimage(0, 0, pageImage.getWidth(), targetHeight);
					}
					graphics.dispose();
				}
				ByteArrayOutputStream os = new ByteArrayOutputStream();
				ImageIO.write(combinedImage, "png", os);
				return java.util.Base64.getEncoder().encodeToString(os.toByteArray());
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return "";
	}

	/**
	 * apache.pdfbox
	 * 速度比icepdf 慢了一倍
	 * @param inputStream
	 * @return
	 */
	public static String icePdfToImage(InputStream inputStream) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try (PDDocument doc = PDDocument.load(inputStream)) {
			PDFRenderer pdfRenderer = new PDFRenderer(doc);
			if (doc.getNumberOfPages() > 0) {
				//方式1 缩放因子
				BufferedImage image = pdfRenderer.renderImage(0, 2f);
				//方式2  DPI因素
				//BufferedImage img = pdfRenderer.renderImageWithDPI(0, 100, ImageType.RGB);

				ImageIO.write(image, "png", os);
			}
			//方式1 速度更快
			String s = java.util.Base64.getEncoder().encodeToString(os.toByteArray());
			//方式2
			//String str = org.apache.tomcat.util.codec.binary.Base64.encodeBase64String(os.toByteArray());
			return s;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	public static String decodeStringToStr(String base64Data) {
		return decodeStringToStr(base64Data, "UTF-8");
	}

	public static String decodeStringToStr(String base64Data, String charset) {
		byte[] bytes = decodeString(base64Data);
		return new String(bytes, Charset.forName(charset));
	}



	public static byte[] decodeString(String base64Data) {
		if (base64Data == null) {
			return null;
		}
		try {
			// 直接使用java.util.Base64进行解码，无需手动处理负数
			return java.util.Base64.getDecoder().decode(base64Data);
		} catch (IllegalArgumentException  e) {
			System.out.println("decodeString is error " + e.getMessage());
			return null;
		}
	}


	// 获取PDF最后一页图片（如果是空页则取前一页）
	public static BufferedImage getLastPdfPageImage(byte[] pdfBytes) throws IOException {
		try (PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes))) {
			PDFRenderer renderer = new PDFRenderer(document);

			int lastPage = document.getNumberOfPages() - 1;
			BufferedImage image = renderer.renderImage(lastPage,2);

			// 检查是否是空页
			if (isBlankImage(image) && lastPage > 0) {
				image = renderer.renderImage(lastPage - 1,2);
			}
			return image;
		}
	}

	// 检查图片是否为空
	private static boolean isBlankImage(BufferedImage image) {
		// 检查像素是否大部分为白色
		// 优化版：检查左上角200x200区域是否全白
		int sampleWidth = Math.min(200, image.getWidth());
		int sampleHeight = Math.min(200, image.getHeight());

		for (int x = 0; x < sampleWidth; x++) {
			for (int y = 0; y < sampleHeight; y++) {
				int rgb = image.getRGB(x, y);
				// 如果不是白色（考虑透明度）
				if ((rgb & 0x00FFFFFF) != 0x00FFFFFF) {
					return false;
				}
			}
		}
		return true;
	}

}
